/*jo对layui的适配*/
(function () {
    console.info('Jo adapter for Layui is loading...');
    if (typeof (layer) == "undefined" || !layer) {
        console.error("jo-adapt-layui初始化失败:缺少layer依赖!");
        return;
    }
    if (typeof (layui) == "undefined" || !layui) {
        console.error("jo-adapt-layui初始化失败:缺少layui依赖!");
        return;
    }
    if (typeof (jo) == "undefined" || !jo) {
        console.error("jo-adapt-layui初始化失败:缺少jo依赖!");
        return;
    }
    /*if(typeof (joView) == "undefined" || !joView){
        console.error("jo-adapt-layui初始化失败:缺少joView依赖!");
        return;
    }*/

    //对Grid适配
    if (typeof (GRID_LAY_ADAPT) != "undefined" && GRID_LAY_ADAPT) {
        console.info("jo-adapt-layui初始化:Grid启用适配!");
        //重写Grid组件
        window.Grid = function (jqGridElement) {
            if (typeof (jqGridElement) == "string") {//当传入表格id时
                if (GridTool[jqGridElement]) {//如果已存在,返回引用
                    return GridTool[jqGridElement];
                } else {
                    //必须使用new关键字,原先不使用new关键字的方式会导致this指向的是window对象(不是我们想要的Grid对象)
                    return new Grid($("#" + jqGridElement));
                    //jqGridElement = $("#"+jqGridElement);
                }
            }
            this.obj = $(jqGridElement);//记录该Grid对象(jq对象)
            this.dataUrl = jo.getDefVal(this.obj.attr("dataUrl"), "");//数据源url
            this.deleteUrl = jo.getDefVal(this.obj.attr("deleteUrl"), "");//删除数据的url
            this.formUrl = jo.getDefVal(this.obj.attr("formUrl"), "");//打开表单对应的url
            this.cols = new Array();//Col对象数组
            this.data = null;//表格数据
            this.titleInited = false;//标记标题初始化状态
            this.titleCss = jo.getDefVal(this.obj.attr("titleCss"), "");//标题行样式
            this.trClick = jo.getDefVal(this.obj.attr("trClick"), "");//行点击事件方法名,推荐不带括号
            this.noHead = jo.getDefVal(this.obj.attr("noHead"), "false");//不要标题行
            this.trHandle = jo.getDefVal(this.obj.attr("trHandle"), "");//行处理函数,生成表格行之前的行对象处理,参数1为行数据对象,参数2为在数据中的位置索引
            if (typeof this == "object") {
                this.id = this.obj.attr("id");
                GridTool[this.id] = this;//将此Grid引用存入池中,方便下次获取
            }
            //layui相关参数
            this.layTable = null;//laytable对象
            this.height = jo.getDefVal(this.obj.attr("lay-height"), "");//高度
            this.page = jo.getDefVal(this.obj.attr("page"), "");//是否开启分页
            if (this.page == "true") {
                this.page = true;
            } else {
                this.page = false;
            }
            //初始化
            var _cols = this.obj.find("col");
            if (_cols && _cols.length > 0) {//存在col配置
                for (var i = 0; i < _cols.length; i++) {
                    var col = new Col($(_cols[i]));
                    if (col.order) {
                        col.sort = true;//col配置转为layui配置
                    }
                    var minWidth = jo.getDefVal($(_cols[i]).attr("minWidth"), "");//最小宽度
                    if (minWidth) {
                        col.minWidth = minWidth;
                    }
                    this.cols.push(col);
                    jo.remove(_cols[i]);//记录结束col数据后删除,原因: 不删除会影响宽度属性异常
                }
            }

            //添加thead和tbody标签,用于存放标题行和内容
            this.obj.html("<thead></thead><tbody></tbody>");

            //返回该Grid对象的colsInfo信息,供joView使用
            this.colsInfo = function () {
                var _colsInfo = new Array();
                for (var i = 0; i < this.cols.length; i++) {
                    _colsInfo.push(this.cols[i].col2Json());
                }
                return _colsInfo;
            };
            //初始化标题行
            this.initTitle = function () {
                //存在属性noHead=true时不生成标题行
                if (this.noHead == "true" || this.noHead == true || this.noHead == "1" || this.noHead == "yes") {
                    return;
                }
                if (jo.isValid(this.cols)) {
                    this.titleInited = true;
                }
            };
            //清空数据
            this.clearData = function () {
                //this.obj.find(">tbody").html("");
                this.data = null;
            };
            //(私有方法)加载json数组数据,加载数据核心实现
            this.loadJsonArray = function (aJson) {
                this.clearData();//清空数据
                if (jo.isValid(this.cols)) {
                    for (var m = 0; m < aJson.length; m++) {
                        var item = aJson[m];//一条json
                        //行数据处理
                        if (jo.isValid(this.trHandle)) {
                            if (this.trHandle.lastIndexOf("()") > -1) {
                                //去除()
                                this.trHandle = this.trHandle.replace("()", "");
                            }
                            try {
                                //eval的方式经过jo.obj2JsonStr(item)后与item不是同一个对象,导致钩子函数无法对item做处理
                                //eval(this.trHandle + "(" + jo.obj2JsonStr(item) + ", " + m + ")");
                                if (typeof (window[this.trHandle]) == "function") {
                                    window[this.trHandle](item, m);
                                }
                            } catch (err) {
                                console.error("行处理方法" + this.trHandle + "异常!");
                                console.info(err);
                            }
                        }
                        var _html = '';
                        if (jo.isValid(this.trClick)) {
                            if (this.trClick.lastIndexOf("()") > -1) {
                                //去除()
                                this.trClick = this.trClick.replace("()", "");
                            }
                            _html = '<tr style="cursor:pointer;" onclick=\'' + this.trClick + '(' + jo.obj2JsonStr(item) + ',' + jo.obj2JsonStr(aJson) + ',' + m + ')\'>';
                        } else {
                            _html = '<tr>';
                        }
                        for (var i = 0; i < this.cols.length; i++) {
                            var col = this.cols[i];
                            var _val = col.field;//col对象配置的field属性
                            //对可执行字段进行处理
                            if (jo.isValid(_val)) {
                                //以 [= 开头, ] 结尾的格式,表示调用函数对字段进行处理,其中的变量(即该行json的字段值)要使用花括号括起来,例如 [=jo.formatDate('{time}')],time为从数据库查询出来的字段
                                if (_val && /^\[=(.)*\]$/.test(_val)) {
                                    //去掉无效的[=和]
                                    _val = _val.substring(2, _val.length - 1);
                                    //解析{xx}类型的变量
                                    _val = jo.getCode(_val, item);
                                    //执行该函数
                                    _val = eval(_val);
                                } else if (/\{(.)*\}/g.test(_val)) {//解析{xx}类型的变量
                                    _val = jo.getCode(_val, item);
                                } else if (_val && _val == "_seq") {//序号常量,自动生成序号
                                    _val = m + 1;
                                } else {
                                    _val = jo.getDefVal(item[_val], "");//正常字段名则从json中取对应字段值
                                }
                            }
                            _val = jo.getDefVal(_val, "");//最后对_val进行检查,无效则赋值空格
                            //将最终的值赋值给json
                            item[col.field] = _val;

                            _html += '<td style="text-align:' + col.align + ';">';
                            if (col.type == 'checkbox') {
                                _html += '<input type="checkbox" name="' + col.field + '" value="' + _val + '"/>';
                            } else if (col.type == 'radio') {
                                _html += '<input type="radio" name="' + col.field + '" value="' + _val + '"/>';
                            } else {
                                _html += _val;
                            }
                            _html += '</td>';
                        }
                        _html += "</tr>";
                        //this.obj.find(">tbody").append(_html);
                    }
                    this.data = jo.getDefVal(aJson, []);

                    this.layTable = layui.table.render({
                        elem: this.obj[0]
                        , height: this.height
                        //,url: '/demo/table/user/' //数据接口
                        , data: this.data
                        , page: this.page //是否开启分页
                        , limit: (this.page ? 10 : this.data.length)
                        , limits: [10, 25, 50, 75, 100]
                        , text: {none: '暂无数据！'}
                        , title: ''	//表格大标题
                        , autoSort: true 	//前端排序,若等于false,需要通过监听排序事件来做后端排序
                        , cols: [this.cols]
                    });
                }
            };
            //加载数据
            this.loadData = function (dataOrUrl) {
                if (!this.titleInited) {
                    this.initTitle();//标题未初始化则先初始化标题
                }
                //var _id = 'loading_' + jo.getUUID();
                //this.obj.find(">tbody").html('<tr id="'+_id+'"><td colspan="'+this.cols.length+'">正在加载...</td></tr>');
                if (typeof (dataOrUrl) == "object" && dataOrUrl instanceof Array) {//传入的数组
                    this.loadJsonArray(dataOrUrl);
                    //$("#"+_id).remove();
                } else {//通过url加载
                    var surl = jo.getDefVal(dataOrUrl, this.dataUrl);
                    if (jo.isValid(surl)) {
                        var _this = this;//将this引用指向变量,因为这个this的作用域不在ajax回调当中
                        jo.postAjax(surl, {}, function (json) {
                            if (json && json.code == "0") {
                                _this.loadJsonArray(json.data);
                            } else if (json && json.code == "-1") {
                                jo.showMsg(json.info);
                            }
                            //$("#"+_id).remove();
                        }, true);
                    } else {
                        //$("#"+_id).remove();
                    }
                }

            };
        }
    }

    //对joView适配
    if (typeof (joView) == "object") {
        //初始化视图参数
        joView.initViewParams = function () {
            var checkStyle = jo.getDefVal(joView.params["checkStyle"], "");
            if (joView.params["colsInfo"]) {
                if (checkStyle == "checkBox") {//复选框
                    joView.params["colsInfo"].unshift({type: 'checkbox', width: joView.params["checkStyleWidth"]});
                    //_html += "<td style=\"text-align: center;\"><input type='checkbox' id='"+joView.params["PKName"]+"' name='"+joView.params["PKName"]+"' value='"+oList[i][joView.params["PKName"]]+"'/></td>";//复选框
                } else if (checkStyle == "radio") {//单选框
                    joView.params["colsInfo"].unshift({type: 'radio', width: joView.params["checkStyleWidth"]});
                } else if (checkStyle == "order") {
                    joView.params["colsInfo"].unshift({type: 'numbers', width: joView.params["checkStyleWidth"]});
                } else {
                    //不要选择框
                }
            }
        };
        //初始化标题行
        joView.initGridHead = function () {
            //不需要操作
        };
        //清空表格
        joView.clearGrid = function () {
            //不需要操作
        };
        //展示数据
        joView.loadData = function (url, formData, goPage, pageSize) {
            if (!goPage) {
                goPage = 1;//默认第一页
            }
            if (!pageSize) {
                pageSize = 0;
            }
            var showFieldsInfo = joView.params["colsInfo"];

            //var list = jo.getDefVal(oList, []);
            var options = {
                elem: joView.Grid.obj[0]
                //,height: joView.Grid.height
                , url: joView.buildSearchUrl() //joView.params["url"]//joView.params['dataUrl'] //数据接口
                , method: 'post'
                , where: joView.buildSearchParam()
                , contentType: 'application/x-www-form-urlencoded'
                , parseData: function (res) {//参数名适配
                    joView.dealSearchResult(res.data, res);
                    return res;
                }
                , request: {
                    pageName: 'pageNumber'
                    , limitName: 'pageSize'
                }
                , response: {
                    statusName: 'code' //规定数据状态的字段名称，默认：code
                    , statusCode: 0 //规定成功的状态码，默认：0
                    , msgName: 'info' //规定状态信息的字段名称，默认：msg
                    , countName: 'total' //规定数据总数的字段名称，默认：count
                    , dataName: 'data' //规定数据列表的字段名称，默认：data
                }
                //,data: list
                , page: joView.params['page'] //是否开启分页
                , limit: pageSize
                , limits: joView.params['pageSizeArr']
                , text: {none: '暂无数据！'}
                , title: ''	//表格大标题
                , autoSort: false 	//前端排序,若等于false,需要通过监听排序事件来做后端排序
                , cols: [showFieldsInfo]
                , done: function (res, curr, count) {
                    //更新页大小
                    if (joView.layTable) {
                        joView.params["pageSize"] = joView.layTable.config.limit;
                    }
                    //后置处理
                    if (typeof (joView.setGridDataAfter) == "function") {
                        joView.setGridDataAfter(res.data);
                    }

                }
            };

            joView.layTable = layui.table.render(options);
        };
        //分页
        joView.showPageInfo = function (result) {
            //不需要操作
        };
        //构建查询url,layui专属
        joView.buildSearchUrl = function () {
            if (joView.params["condition"] && typeof (joView.params["condition"]) == 'string') {//字符串类型
                joView.params["url"] = joView.params["dataUrl"] + jo.getLinkSign(joView.params["dataUrl"]) + joView.params["condition"];
            } else {
                joView.params["url"] = joView.params["dataUrl"];
            }
            var sUrl = jo.parseUrl(joView.params["url"]);//解析url

            return sUrl + jo.getLinkSign(sUrl) + REQUEST_DATA_KEY_TOKEN + '=' + SSO_TOKEN;
        };
        //构建查询参数,layui专属
        joView.buildSearchParam = function () {
            if (jo.isValid(joView.params["dataUrl"])) {
                //每次加载都要刷新url和formData参数(如果有的话)
                if (jo.isValid(document.getElementById("pageForm"))) {
                    joView.params["formData"] = jo.form2Json(jo._("#pageForm"));//new FormData($("#pageForm")[0]);
                } else {
                    joView.params["formData"] = {};//new FormData($("#pageForm")[0]);
                }
                //为了避免查询表单中参数名与排序参数重复
                if (typeof (joView.params["formData"]["orderBy"]) != "undefined" || typeof (joView.params["formData"]["orderType"]) != "undefined") {//表单存在orderBy或orderType关键字
                    console.warn("[joView列表查询] 检索表单中存在orderBy或orderType参数字段,与joView排序功能关键字产生冲突!这将导致您的自定义排序功能失效!");
                } else {
                    //插入排序参数
                    joView.params["formData"]["orderBy"] = joView.params["orderBy"];
                    joView.params["formData"]["orderType"] = joView.params["orderType"];
                }
                //额外携带condition自定义查询参数
                if (joView.params["condition"] && typeof (joView.params["condition"]) == 'string') {//字符串类型
                    joView.params["url"] = joView.params["dataUrl"] + jo.getLinkSign(joView.params["dataUrl"]) + joView.params["condition"];
                } else if (joView.params["condition"] && typeof (joView.params["condition"]) == 'object') {//object类型
                    joView.params["formData"] = $.extend({}, joView.params["formData"], joView.params["condition"]);//将参数聚合到一起
                    joView.params["url"] = joView.params["dataUrl"];
                } else {
                    joView.params["url"] = joView.params["dataUrl"];
                }

            }
            var data = joView.params["formData"];
            if (typeof (processRequestData) == "function") {
                data = processRequestData(data, "joView");//数据加工
            }
            return data;
        };
        joView.dealSearchResult = function (oList, oResult) {
            var showFieldsInfo = joView.params["colsInfo"];
            var checkStyle = jo.getDefVal(joView.params["checkStyle"], "");
            var currentPage = 1;//当前页
            var pageSize = 0;//每页多少条
            if (oResult && oResult.pageNumber) {
                currentPage = oResult.pageNumber;
            }
            if (oResult && oResult.pageSize) {
                pageSize = oResult.pageSize;
            }

            /*
             * 生成数据行
             */
            if (typeof (joView.setGridDataBefore) == "function") {//生成数据行的前置处理
                try {
                    joView.setGridDataBefore(oList);
                } catch (err) {
                    jo.showMsg("joView.setGridDataBefore方法异常!");
                }
            }
            if (typeof (joView.setGridData) == "function") {//生成Grid数据接管函数
                /*try{
                    joView.setGridData(oList);
                }catch(err){
                    jo.showMsg("joView.setGridData方法异常!");
                }*/
                console.warn('layui版本的joView不支持setGridData函数');
            }

            for (var i = 0; i < oList.length; i++) {

                //处理数据行对象
                if (typeof (joView.handleItem) == "function") {
                    joView.handleItem(oList[i], i);
                }

                //遍历生产数据行
                for (var j = 0; j < showFieldsInfo.length; j++) {
                    //判断td内容的align属性,默认居中
                    var sAlign = jo.getDefVal(showFieldsInfo[j]["align"], "left");
                    var alignHtml = ' align=\"' + sAlign + '\"';
                    var _val = jo.parseExpression(showFieldsInfo[j]['field'], oList[i], (currentPage - 1) * pageSize + i);//解析表达式
                    var tips = jo.parseExpression(showFieldsInfo[j]['tips'], oList[i], (currentPage - 1) * pageSize + i);//解析表达式

                    //2017-05-06修改:将点击事件挂在td上,取消掉之前的a标签
                    if (typeof (joView.handleItemValue) == "function") {//该接管函数对每个格子的值进行复制,不适用上面解析后的值
                        oList[i][showFieldsInfo[j]['field']] = (oList[i][showFieldsInfo[j]['field']] ? joView.handleItemValue(oList[i][showFieldsInfo[j]['field']], j) : '&nbsp;');
                    } else {//使用.replace(/\'/ig,"\\\"")是为了解决因为单引号造成的显示问题和点击事件异常
                        var evt = showFieldsInfo[j]['event'];
                        if (evt == "none") {//event属性为none时表示禁用点击事件
                            oList[i][showFieldsInfo[j]['field']] = _val;
                        } else if (evt == 'click') {
                            oList[i][showFieldsInfo[j]['field']] = "<span onclick='joView.edit(\"" + oList[i][joView.params["PKName"]] + "\"," + JSON.stringify(oList[i]).replace(/\'/ig, "\\\"") + ")'><a href='javascript:;'>" + _val + "</a></span>";
                        }
                    }
                }

            }
        };
        //获取选中值
        joView.getCheckBoxValue = function (name) {
            if (!name) {
                name = joView.params["PKName"];
            }
            var checkStatus = layui.table.checkStatus(joView.Grid.id);

            var arr = [];
            for (var i = 0; i < checkStatus.data.length; i++) {
                arr.push(checkStatus.data[i][name]);
            }
            if (arr.length == 0) {
                return '';
            }
            return arr.join(',');
        };
        //重写jo的获取多选框值是为了兼容已有的代码,有的页面里面会有取值操作
        jo.getCheckBoxValueOld = jo.getCheckBoxValue;
        jo.getCheckBoxValue = function (name) {
            if (joView.inited) {
                var val = jo.getCheckBoxValueOld(name);
                if (val) {
                    console.warn('当前获取多选框值使用的原始getCheckBoxValue方法,检测到当前页面joView对象已加载,请确认取值是否正确(取layui表格中的多选框结果建议使用joView.getCheckBoxValue方法).若取值正确请忽略该消息.');
                    return val;
                }
                return joView.getCheckBoxValue(name);
            }
            return jo.getCheckBoxValueOld(name);
        };

    }


})();